package com.guan.core.util;
/**
 * 扫描制定包下的类并返回集合
 *
 * @author Administrator
 */

import java.io.File;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class ClassScanner {
    /**
     * 根据包传入的包路径下的所有类 com/guan/entity
     * @param packagePath
     * @return
     */
    public static Map<String, Class<?>> scannerClass(String packagePath) {
        //把点替换成 /
        String filePath = packagePath.replace(".", "/");
        Map<String, Class<?>> result = new HashMap<String, Class<?>>();
        try {
            //取得给定路径的所有URL地址枚举对象,获得多个URL路径，类路径和jar都存在的情况，会有两个
            Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(filePath);
            //通过字符串截取一个根路径,类路径
            String rootPath = filePath;
            //迭代所有的类路径（包含jar包中同包的路径下的类，所以分为两种处理方式）
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                //通过URL去判断是文件还是其他的
                if (url.getProtocol().equals("file")) {//类路径的处理方式
                    File folder = new File(url.getPath());
                    //扫描文件夹下所有的类，包括子包-子文件
                    scannerFile(folder, rootPath, result);
                } else if (url.getProtocol().equals("jar")) {
                    //jar包的处理方法JarURLConnection
                    JarURLConnection connection = (JarURLConnection) url.openConnection();
                    if (connection != null) {
                        //jar文件对象
                        JarFile jarFile = connection.getJarFile();
						if(null != jarFile){
						    Enumeration<JarEntry> jarEntrys = jarFile.entries();
						    while (jarEntrys.hasMoreElements()){
						        //拿到jar包中的实体
						        JarEntry jarEntry = jarEntrys.nextElement();
						        String entryName = jarEntry.getName();
						        if(entryName.endsWith(".class")&&entryName.startsWith(filePath)){
						            String className = entryName.split("\\.")[0];
                                    className = className.replace("/",".");
                                    result.put(className,Class.forName(className));
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            XMLUtil.log(e.getMessage() + "初始化异常");
        }
        return result;
    }

    /**
     * 扫描文件夹下的所有java类
     * @param folder
     * @param rootPath
     * @param result
     */
    private static void scannerFile(File folder, String rootPath, Map<String, Class<?>> result) {
        File[] files = folder.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                //如果是文件夹，递归调用自己
                scannerFile(file, rootPath + "/" + file.getName(), result);
            } else {//是文件的情况下
                //拿到当前文件的真是路径
                String path = file.getAbsolutePath();
                if (path.endsWith(".class")) {
                    //E:\ideaWorkSpace\Online-retailers-parernt\Online-retailers\target\classes\com\guan\entity\AdminUser.class
                    //替换\为 / window 与 linux 都能识别
                    path = path.replace("\\", "/");
                    //获得类路径
                    String className = rootPath + path.substring(path.lastIndexOf("/"), path.indexOf(".class"));
                    className = className.replace("/", ".");
                    System.err.println(className);
                    try {
                        result.put(className, Class.forName(className));
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        scannerClass("org.dom4j");
    }
}
